package com.badshun.badscript;

import java.util.regex.*;
import java.util.*;
//变量类
public class BSVar {
	private String varName;
	private String value;
	private BadScript badscript;
	private int linenum;
	
	//String的格式
	private final String strExp = "^\\s*\"(.*?)\"\\s*$";
	private final String boolExp = "^\\s*(true|false)\\s*$";
	private final String intExp = "^\\s*(\\d+)\\s*$";
	private final String floatExp = "^\\s*(\\d+).(\\d+)\\s*$";
	private final String expExp = "^\\s*(.*?)\\s*(\\+|-|\\*|/)\\s*(.*?)\\s*$";
	
	public BSVar(String varName, String value, BadScript badScript, int linenum) {
		this.badscript = badScript;
		this.linenum = linenum;
		
		setVarName(varName);
		setValue(value);
	}

	public void setVarName(String varName) {
		this.varName = varName;
		
		try {
			//判断标识符是否以数字开头
			if(BSUtils.isStartWithDigital(varName)) {
				badscript.printError("变量名不能以数字开头", linenum);
				throw new BSVarNameStartWithDigitalException();
			}

			for(int i = 0; i < badscript.varMap.keySet().size(); i++) {
				String[] keySetArray = new String[badscript.varMap.keySet().size()];
				String key = (String) badscript.varMap.keySet().toArray(keySetArray)[i];
				//变量名与已存在的变量名冲突
				System.out.println("key:" + key);
				if(varName.equals(key)) {
					badscript.printError("该变量名已被使用", linenum);
					throw new BSVarNameIsUsedException();
				}
			}
			
			for(int i = 0; i < badscript.keywordsArray.length; i++) {
				if(varName.equals(badscript.keywordsArray[i])) {
					badscript.printError("该变量名与关键字冲突", linenum);
					throw new BSVarNameIsUsedException();
				}
			}
		} catch (BSVarNameStartWithDigitalException bsvnswde) {
			bsvnswde.printStackTrace();
		} catch(BSVarNameIsUsedException bsvniue) {
			bsvniue.printStackTrace();
		}
	}

	public String getVarName() {
		return varName;
	}

	public void setValue(String value) {
		this.value = value;
		
		if(value == null) return ;
		
		Matcher valueMatcher = null;
		//判断变量类型（string，number，bool，expression）
		if((valueMatcher = Pattern.compile(strExp).matcher(value)).find()) {
			System.out.println(value + "这个变量是字符串");
		} else if((valueMatcher = Pattern.compile(boolExp).matcher(value)).find()) {
			System.out.println(value + "是个bool类型变量");
		} else if((valueMatcher = Pattern.compile(intExp).matcher(value)).find() || (valueMatcher = Pattern.compile(floatExp).matcher(value)).find()) {
			System.out.println(value + " is a number");
		} else if((valueMatcher = Pattern.compile(expExp).matcher(value)).find()) {
			System.out.println(value + " is an exception");
			workSimpleMathExpression(value);
		} else {
			System.out.println("我不认识");
		}
	}

	public String getValue() {
		return value;
	}
	
	//计算简单数学表达式
	private void workSimpleMathExpression(String expression) {
		//去掉空格
		String exp = expression.replace(" ", "");
		exp = exp.charAt(exp.length() - 1) == '+' ? exp : exp + "+";
		//操作数
		ArrayList<String> number1 = new ArrayList<String>();
		ArrayList<String> number2 = new ArrayList<String>();
		//操作符
		String operator = "";
		
		for(int i = 0; i < exp.length(); i++) {
			String s = exp.charAt(i) + "";
			//存在高优先级操作符
			if(BSUtils.isContain(exp, '*') || BSUtils.isContain(exp, '/')) {
				if(operator.equals("")) {
					if(s.equals("*") || s.equals("/")) {
						operator = s;
					} else if(s.equals("+") || s.equals("-")){
						number1 = new ArrayList<String>();
						number1.add(s);
					} else {
						number1.add(s);
					}
				} else {
					if(number2.size() != 0 && (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/"))) {
						//开始计算
						float num1 = new Float(arrayToString(number1));
						float num2 = new Float(arrayToString(number2));
						float result = operator.equals("*") ? num1 * num2 : num1 / num2;
						
						String currentExp = arrayToString(number1) + operator + arrayToString(number2);
						System.out.println("result:" + result);
						
						exp = result > 0 ? exp.replace(currentExp, "+" + result + "") : exp.replace(currentExp, result + "");
						
						String last = exp.substring(1, exp.length() - 1);
						if(BSUtils.isContain(last, '+') || BSUtils.isContain(last, '-') || BSUtils.isContain(last, '*') || BSUtils.isContain(last, '/')) {
							workSimpleMathExpression(exp);
							return;
						} else {
							System.out.println("over");
							return;
						}
					} else {
						number2.add(s);
					}
				}
				//不存在高优先级操作符
			} else {
				if(number1.size() == 0 && (s.equals("+") || s.equals("-"))) {
					number1.add(s);
					continue;
				}
				
				if(operator.equals("")) {
					if(s.equals("+") || s.equals("-")) {
						operator = s;
						System.out.println(operator);
					} else {
						number1.add(s);
					}
				} else {
					if(number2.size() != 0 && ((s.equals("+") || s.equals("-")))) {
						//开始计算
						float num1 = new Float(arrayToString(number1));
						float num2 = new Float(arrayToString(number2));
						float result = operator.equals("+") ? num1 + num2 : num1 - num2;

						String currentExp = arrayToString(number1) + operator + arrayToString(number2);
						System.out.println("result:" + result);
						
						exp = result > 0 ? exp.replace(currentExp, "+" + result + "") : exp.replace(currentExp, result + "");

						String last = exp.substring(1, exp.length() - 1);
						if(BSUtils.isContain(last, '+') || BSUtils.isContain(last, '-') || BSUtils.isContain(last, '*') || BSUtils.isContain(last, '/')) {
							workSimpleMathExpression(exp);
							return;
						} else {
							System.out.println("over");
							return;
						}
					} else {
						number2.add(s);
					}
				}
			}
		}
	}
	
	//数组转字符串
	private String arrayToString(ArrayList<String> array) {
		String str = "";
		
		for(int i = 0; i < array.size(); i++) {
			str += array.get(i);
		}
		
		return str;
	}
}
